﻿$import( "SmitearWebGL.Core.ResourceItem" );

SmitearWebGL.Objects.Container = SmitearWebGL.Core.ResourceItem.extend(
{
	/******** constructor ********/

	init : function()
	{
		/******** private property ********/
		
		this._scene = null;
		this._parent = null;
		this._children = null;
		this._childMap = null;
		
		this._super();
		this._registClass( "SmitearWebGL.Objects.Container" );
	}
	,
	
	/******** public method ********/
	
	getScene : function()
	{
		return this._scene;
	}
	,
	getParent : function()
	{
		return this._parent;
	}
	,
	getChildAt : function( index )
	{
		return this._children[index];
	}
	,
	getChildByName : function( name )
	{
		return this.getChildAt(_childMap[name]);
	}
	,
	addChild : function( child )
	{
		if ( child._parent || child._scene )
		{
			$WARNING( child.name + "已存在父节点" );
			return false;
		}
		child._parent = this;
		child._childrenListIdx = this._children.length;
		this._childMap[child.name] = this._children.length;
		this._children.push( child );
		
		if ( this._scene )
		{
			this._addToScene( child );
		}
		
		return true;
	}
	,
	removeChild : function( child )
	{
		if ( child._parent != this )
		{
			$WARNING( child.name + "不是子节点" );
			return false;
		}
		
		for ( var i = 0; i < this._children.length; ++ i )
		{
			if ( child == this._children[i] )
			{
				this.removeChildAt(i);
				break;
			}
		}
		
		return true;
	}
	,
	removeChildByName : function( name )
	{
		var child = this.getChildByName( name );
			
		if ( ! child )
		{
			$WARNING( "找不到名称为" + name + "的子节点" );
			return false;
		}
		
		if ( child._parent != this )
		{
			$WARNING( name + "不是子节点" );
			return false;
		}
		
		return this.removeChild( child );
	}
	,
	removeChildAt : function( index )
	{
		if ( index < 0 || index >= this._children.length )
		{
			$WARNING( "索引无效" );
			return false;
		}
		
		var child = this._children.splice( index, 1 )[0];
		child._parent = null;
		delete this._childMap[child.name];
		
		if ( child._scene )
		{
			this._removeFromScene( child );
		}
		
		return true;
	}
	,
	foreach : function( func )
	{
		for( var i = 0; i < this._children.length; ++ i)
		{
			func( this._children[i] );
		}
	}
	,
	
	/******** private method ********/
	
	_addToScene : function( child )
	{
		if ( child.scene )
			this._removeFromScene( child );
		
		child._scene = this._scene;
		
		this._scene._displayObjects.push( child );
		
		if ( child.getDisplayType() == SmitearWebGL.Objects.Entity.DisplayType.MESH )
		{
			this._scene._renderObjects.push( child );
		}
		
		if ( child.getDisplayType() == SmitearWebGL.Objects.Entity.DisplayType.LIGHT )
		{
			this._scene._lights.push( child );
		}
		
		for( var i = 0; i < child._children.length; ++ i )
		{
			this._addToScene( child._children[i] );
		}
	}
	,
	_removeFromScene : function( child )
	{
		var i;
		
		for ( i = 0; i < this._scene._displayObjects.length; ++ i )
		{
			if ( child == this._scene._displayObjects[i] )
			{
				this._scene._displayObjects.splice( i, 1 );
				break;
			}
		}
		
		if ( child.getDisplayType() == SmitearWebGL.Objects.Entity.DisplayType.MESH )
		{
			for ( i = 0; i < this._scene._renderObjects.length; ++ i )
			{
				if ( child == this._scene._renderObjects[i] )
				{
					this._scene._renderObjects.splice( i, 1 );
					this._scene.getQuadTree().removeSceneObject( child )
					break;
				}
			}
		}
		
		if ( child.getDisplayType() == SmitearWebGL.Objects.Entity.DisplayType.LIGHT )
		{
			for ( i = 0; i < this._scene._lights.length; ++ i )
			{
				if ( child == this._scene._lights[i] )
				{
					this._scene._lights.splice( i, 1 );
					break;
				}
			}
		}
		
		child._scene = null;
		
		for( i = 0; i < child._children.length; ++ i)
		{
			this._removeFromScene( child._children[i] );
		}
	}
	,
	_createResource : function( params )
	{
		this._super();
		
		this._scene = null;
		this._parent = null;
		this._children = [];
		this._childMap = {};
	}
	,
	_destroyResource : function()
	{
		this._super();
		
		this._scene = null;
		this._parent = null;
		this._children = null;
		this._childMap = null;
	}
}
);